import axios from 'axios'
import {uid} from 'quasar'
import {getMaxPage, getOssToken, getResponse, handleError} from '../utils/request'

const LIMIT = 10

export const maxPageMixin = {
  computed: {
    maxPage() {
      return getMaxPage(this.count, this.limit)
    }
  }
}

export const uploadOssMixin = {
  data: {
    maxSize: 4
  },
  methods: {
    async readFile(file) {
      return new Promise((resolve, reject) => {
        const reader = new FileReader()
        reader.readAsDataURL(file)

        reader.onload = function (e) {
          resolve(e.target.result)
        }
      })
    },
    async getImageSize(dataUrl) {
      return new Promise((resolve, reject) => {
        let img = new Image()

        img.src = dataUrl

        img.onload = function () {
          resolve({
            height: this.height,
            width: this.width
          })
        }
      })
    },
    /**
     *
     * @param {File} file
     * @param {string} path
     * @param {Object} size
     * @returns {Promise<{data, status}>}
     */
    async uploadOssFile(file, path, size) {
      let format
      const ossHostUrl = 'https://ageeye-user-image.oss-cn-hangzhou.aliyuncs.com/'

      switch (file.type) {
        case 'image/jpeg':
          format = 'jpg'
          break
        case 'image/png':
          format = 'png'
          break
        case 'image/gif':
          format = 'gif'
          break
        default:
          return {status: 500, data: {msg: '文件格式错误'}}
      }


      const uuid = uid()
      const {width, height} = size

      const {data, status} = await getOssToken(path)

      if (status !== 200) {
        return {status: 500}
      }

      const formData = new FormData()
      const name = `${uuid}_${width}_${height}.${format}`
      const key = data.dir + name
      const url = ossHostUrl + key

      formData.append('name', name)
      formData.append('key', key)
      formData.append('url', url)
      formData.append('policy', data.policy)
      formData.append('OSSAccessKeyId', data.accessid)
      formData.append('success_action_status', 200)
      formData.append('signature', data.signature)
      formData.append('file', file)

      try {
        const res = await axios.post(data.host, formData, {'Content-Type': 'multipart/form-data'})
        res.data = {url}

        return getResponse(res)
      } catch (e) {
        return handleError(e)
      } finally {
      }
    },
    async uploadServerFile(file, size) {
      const api = '/api/upload/'

      const formData = new FormData()
      formData.append('filename', file)

      try {
        const res = await axios.post(api, formData, {'Content-Type': 'multipart/form-data'})
        return getResponse(res)
      } catch (e) {
        return handleError(e)
      } finally {
      }
    }
  }
}

export const querySetBaseMixin = {
  methods: {
    /**
     *
     * @param {string} mode set|add
     * @returns {Promise<void>}
     */
    async query(mode) {
      const options = {
        api: this.api,
        page: this.page,
        limit: this.limit || LIMIT,
        type: this.type,
        id: this.id
      }

      if (this.queryParams) {
        options.params = this.queryParams
      }

      if (mode) {
        options.mode = mode
      }

      await this.getQuerySet(options)
    },
    async nextPage() {
      if (!this.nextPageQuery || this.loading) {
        return
      }
      const api = process.env.NODE_ENV === 'development' ? this.nextPageQuery.replace(/http:\/\/.*?(?=\/)/, '') : this.nextPageQuery

      if (this.loading !== undefined) {
        this.loading = true
      }

      const options = {}

      if (this.$store.state.auth) {
        options.headers = {Authorization: this.$store.state.auth.token}
      }

      try {
        const res = await this.$axios.get(api, options)
        const data = res.data

        this.querySet = this.querySet.concat(data.results)
        this.count = data.count

        if (this.nextPageQuery !== undefined) {
          this.nextPageQuery = data.next
        }

        return getResponse(res)
      } catch (e) {
        console.log(e)
        return handleError(e)
      } finally {
        if (this.loading !== undefined) {
          this.loading = false
        }
      }
    },
    getInstanceRow(id) {
      if (!id) {
// eslint-disable-next-line no-throw-literal
        throw 'no id'
      }

      if (this.querySet) {
        for (let i = 0; i < this.querySet.length; i++) {
          if (this.querySet[i].id === id) {
            return i
          }
        }

        return NaN
      } else {
        return NaN
      }
    },
    async update({api, id, data, method = 'put'}) {
      const result = await this[`${method}Request`]({
        api,
        id,
        data
      })

      if (result.status === 200) {
        this.notify('success', '更新状态成功')

        const row = this.getInstanceRow(id)

        if (isNaN(row) === false) {
          this.$set(this.querySet, row, result.data)
          // this.querySet[row] = result.data
        } else {
          this.query()
        }
      } else {
        this.notify('error', '设置状态失败，请稍后重试，或者检查你的网络。')
      }
    },
    async remove({api, id}) {
      const {status} = await this.deleteRequest({
        api,
        id
      })

      if (status === 204) {
        this.notify('success', '删除成功')
        this.query()
      } else {
        this.notify('error', '删除失败，请稍后重试，或者检查你的网络。')
      }
    }
  }
}

export const querySetMixin = Object.assign({
  computed: {
    max() {
      return Math.ceil(this.count / (this.limit || LIMIT))
    },
    queryParams() {
      let query = {}

      if (this.page) {
        query.page = this.page
      }

      if (this.ordering) {
        query.ordering = this.ordering
      }

      if (this.category) {
        query.category = this.category
      }

      if (this.search) {
        query.search = this.search
      }

      return query
    },
    more() {
      return this.max > this.page
    }
  },
  props: {
    page: {
      type: [Number, String],
      required: false,
      default: 1
    },
    createdQuery: {
      type: Boolean,
      required: false,
      default: true
    },
    updateSetMode: {
      type: String,
      required: false,
      default: 'set'
    },
    updateRoute: {
      type: Boolean,
      required: false,
      default: true
    }
  },
  data() {
    return {
      // api: '',
      // limit: LIMIT,
      nextPageQuery: null,
      loading: false,
      count: 0,
      querySet: null
    }
  },
  watch: {
    queryParams(query) {
      if (this.updateRoute) {
        const route = this.getRoute({query})
        this.$router.push(route)
      }
      this.query()
    }
  },
  created() {
    if (this.createdQuery) {
      this.query()
    }

    this.$root.$on('scrollBottom', () => {
      if (this.infinite) {
        this.nextPage()
      }
    })
  }
}, querySetBaseMixin)

export const querySetInfiniteMixin = Object.assign({
  props: {
    updateSetMode: {
      type: String,
      required: false,
      default: 'set'
    }
  },
  data() {
    return {
      // api: '',
      page: 1,
      nextPageQuery: null,
      loading: false,
      count: 0,
      querySet: null
    }
  },
  watch: {}
}, querySetBaseMixin)
